//Erstellt von Moritz Liepe
package main;

import java.io.*;

import main.editor.VOSEditor;

import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.w3c.dom.*;


import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;

public class XMLWriter{

	private String filename = "";
	
	public XMLWriter(String fn){
		filename = fn;
	}
	
	public void saveXMLDocument(){
		PrintWriter out = null;
		try{
			out = new PrintWriter(filename);
		} catch(FileNotFoundException fe){
			fe.printStackTrace();
		}
		Document xmldoc = null;
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = null;
		try{
			builder = factory.newDocumentBuilder();
		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		}
		DOMImplementation impl = builder.getDOMImplementation();
		Element parentNode = null;
		Element moduleChild = null;
		Element moduleChildChild = null;
		Node n = null;
		xmldoc = impl.createDocument(null, "VisumOSProgram", null);
		Element root = xmldoc.getDocumentElement();
		
		//Get the current Editor Instance and write all Modules and Connections
		VOSEditor vosEditor;
		IEditorPart page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
		if((page != null) && (page instanceof VOSEditor)){
			vosEditor = (VOSEditor)page;
			ModuleEditor mEditor = vosEditor.getModuleEditor();
			//Define temporary Module Strings
			String titleImage,titleText, posX, posY, width, 
			height, ID, SIMID, ClassName, connectable, type, address, 
			tooltip, controlText;
			//Define temporary Connections Strings
			String sourceModuleID, targetModuleID, sourceAnchorID, targetAnchorID;
			//Loop through Elements in Editor
			for(int i=0; i < mEditor.getChildren().size(); i++){
				if(mEditor.getChildren().get(i) instanceof Module){
					Module currentModule = (Module)mEditor.getChildren().get(i);
					
					ID = currentModule.getID();
					SIMID = currentModule.getSIMID();
					width = ((Integer)currentModule.getWidth()).toString();
					height = ((Integer)currentModule.getHeight()).toString();
					posX = ((Integer)currentModule.getLocation().x).toString();
					posY = ((Integer)currentModule.getLocation().y).toString();
					titleImage = currentModule.getTitleImagePath();
					titleText = currentModule.getTitle().getText();
					//Create Module and Title Elements
					parentNode = xmldoc.createElementNS(null, "module");
					parentNode.setAttributeNS(null, "ID", ID);
					parentNode.setAttributeNS(null, "SIMID", SIMID);
					parentNode.setAttributeNS(null, "WIDTH", width);
					parentNode.setAttributeNS(null, "HEIGHT", height);
					parentNode.setAttributeNS(null, "X", posX);
					parentNode.setAttributeNS(null, "Y", posY);
					moduleChild = xmldoc.createElementNS(null, "title");
					moduleChildChild = xmldoc.createElementNS(null, "img");
					n = xmldoc.createTextNode(titleImage);
					moduleChildChild.appendChild(n);
					moduleChild.appendChild(moduleChildChild);
					moduleChildChild = xmldoc.createElementNS(null, "text");
					n = xmldoc.createTextNode(titleText);
					moduleChildChild.appendChild(n);
					moduleChild.appendChild(moduleChildChild);
					parentNode.appendChild(moduleChild);
					//Create Controls Elements
					for(int y = 1; y < currentModule.getChildren().size(); y++){ //skip the title Label, begin with 1
						IModuleControl child = (IModuleControl)currentModule.getChildren().get(y);
						ClassName = child.getClass().getCanonicalName().toString();
						posX = ((Integer)(child.getBounds().x-child.getParent().getBounds().x-1)).toString();
						posY = ((Integer)(child.getBounds().y-child.getParent().getBounds().y-1)).toString();
						width = ((Integer)child.getWidth()).toString();
						height = ((Integer)child.getHeight()).toString(); 
						ID = child.getID().toString();
						if(child.isConnectable())connectable = "true";
						else connectable = "false";
						type = child.getType();
						address = child.getAddress();
						tooltip = ((Label)child.getToolTip()).getText();
						controlText = "";
						if(child instanceof TextControl){
							controlText = child.getValue();
								
						}
						moduleChild = xmldoc.createElementNS(null, "control");
						moduleChild.setAttributeNS(null, "CLASS", ClassName);
						moduleChild.setAttributeNS(null, "ID", ID);
						moduleChild.setAttributeNS(null, "X", posX);
						moduleChild.setAttributeNS(null, "Y", posY);
						moduleChild.setAttributeNS(null, "WIDTH", width);
						moduleChild.setAttributeNS(null, "HEIGHT", height);
						moduleChild.setAttributeNS(null, "CONNECTABLE", connectable);
						moduleChild.setAttributeNS(null, "TYPE", type);
						moduleChild.setAttributeNS(null, "ADDRESS", address);
						moduleChild.setAttributeNS(null, "TOOLTIP", tooltip);
						if (controlText != "")moduleChild.setAttributeNS(null, "CONTROLTEXT", controlText);
						parentNode.appendChild(moduleChild);
					}
					root.appendChild(parentNode);
				}
				//Create Connection Elements
				else if(mEditor.getChildren().get(i) instanceof PolylineConnection){
					PolylineConnection currentConnection = (PolylineConnection)mEditor.getChildren().get(i);
					IOControl sourceControl = ((IOControl)currentConnection.getSourceAnchor().getOwner());
					IOControl targetControl = ((IOControl)currentConnection.getTargetAnchor().getOwner());
					sourceModuleID = ((Module)sourceControl.getParent()).getID();
					targetModuleID = ((Module)targetControl.getParent()).getID();
					sourceAnchorID = sourceControl.getID().toString();
					targetAnchorID = targetControl.getID().toString();
					parentNode = xmldoc.createElementNS(null, "connection");
					parentNode.setAttributeNS(null, "SOURCEMODULE", sourceModuleID);
					parentNode.setAttributeNS(null, "TARGETMODULE", targetModuleID);
					parentNode.setAttributeNS(null, "SOURCE", sourceAnchorID);
					parentNode.setAttributeNS(null, "TARGET", targetAnchorID);
					root.appendChild(parentNode);
				}
			}
		}
		
		DOMSource domSource = new DOMSource(xmldoc);
		StreamResult streamResult = new StreamResult(out);
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer serializer = null;
		try{
			serializer = tf.newTransformer();
		} catch(TransformerConfigurationException tce){
			tce.printStackTrace();
		}
		serializer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1");
		serializer.setOutputProperty(OutputKeys.INDENT,"yes");
		try{
			serializer.transform(domSource, streamResult); 
		} catch(TransformerException te){
			te.printStackTrace();
		}

	}

}